package com.jms.crawler.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jms.base.context.CustomerContext;
import com.jms.base.entity.requestEntity.ResponseResult;
import com.jms.base.utils.BasicEntryUtil;
import com.jms.crawler.context.DataCrawlContext;
import com.jms.crawler.entity.basicEnity.CrawlTask;
import com.jms.crawler.entity.basicEnity.CrawlTaskStatus;
import com.jms.crawler.entity.basicEnity.CrawlTaskType;
import com.jms.crawler.mapper.CrawlTaskMapper;
import com.jms.crawler.service.DataCrawlService;
import com.jms.crawler.util.FileDownload;
import com.jms.crawler.util.ServiceType;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/crawl")
public class DataCrawlController {
    private final static Logger LOGGER = LogManager.getLogger(DataCrawlController.class);

    @Value("${jms.crawl.path}")
    private String crawlPath;
    private DataCrawlContext dataCrawlContext;
    private CrawlTaskMapper crawlTaskMapper;
    private BasicEntryUtil basicEntryUtil;

    @Autowired
    public void setBasicEntryUtil(BasicEntryUtil basicEntryUtil) {
        this.basicEntryUtil = basicEntryUtil;
    }

    @Autowired
    public void setCrawlTaskMapper(CrawlTaskMapper crawlTaskMapper) {
        this.crawlTaskMapper = crawlTaskMapper;
    }

    @Autowired
    public void setDataCrawlContext(DataCrawlContext dataCrawlContext) {
        this.dataCrawlContext = dataCrawlContext;
    }

    @PostMapping("/start/weibo")
    public ResponseResult startWeiboCrawlService(@RequestBody Map<String, Object> map) {
        ResponseResult result = new ResponseResult();
        try {
            //构造任务基本参数
            Map<String, Object> taskContent = new HashMap<>();
            Map<String, Object> params = new HashMap<>();
            String taskName = ServiceType.getServiceName(ServiceType.WEIBO_SERVICE);
            taskContent.put("taskName", taskName);
            String code = (String) map.get("code");
            String[] important_codes = code.split(",");
            params.put("important_codes", important_codes);
            params.put("cookies", map.get("cookies"));
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String start_date = (String) map.get("start_date");
            String end_date = (String) map.get("end_date");
            Date s_date = sdf.parse(start_date + " 23:59:59");
            Date e_date = sdf.parse(end_date + " 23:59:59");
            params.put("start_date", s_date);
            params.put("end_date", e_date);
            String[] connectFileNames = new String[important_codes.length];
            String[] commentFileNames = new String[important_codes.length];
            for (int i = 0; i < important_codes.length; i++) {
                connectFileNames[i] = crawlPath + "/" + taskName + "_" + important_codes[i] + "_connect.csv";
                commentFileNames[i] = crawlPath + "/" + taskName + "_" + important_codes[i] + "_comment.csv";
            }
            params.put("content_csv_filePaths", connectFileNames);
            params.put("comment_csv_filePaths", commentFileNames);
            taskContent.put("params", params);

            //构造任务数据实体
            CrawlTask crawlTask = new CrawlTask();
            basicEntryUtil.createEntry(crawlTask, CustomerContext.getCurrentCustomer().getId());
            crawlTask.setTaskName(taskName);
            JSONObject content = new JSONObject(taskContent);
            crawlTask.setTaskContent(content.toJSONString());
            crawlTask.setTaskType(CrawlTaskType.WeiBo.name());
            crawlTask.setCreateUser(CustomerContext.getCurrentCustomer().getId());

            if (dataCrawlContext.haveUnusedTasker()) {
                crawlTask.setTaskStatus(CrawlTaskStatus.WAITING.name());
                result.buildCode(200).buildMessage("暂无闲置服务，需等待其它爬取服务完成").buildData(taskName);
            } else {
                crawlTask.setTaskStatus(CrawlTaskStatus.RUNNING.name());
                dataCrawlContext.executeWeiboTask(taskContent);
                result.buildCode(200).buildMessage("爬取服务创建成功").buildData(taskName);
            }
            crawlTaskMapper.insert(crawlTask);
        } catch (Exception e) {
            result.buildCode(50001).buildMessage("操作失败").setData(false);
            LOGGER.error(e.getMessage(), e);
        }
        return result;
    }

    /**
     * 停止爬取服务
     *
     * @param taskName 服务名称
     * @return ResponseResult
     */
    @PostMapping("/stop")
    public ResponseResult stopCrawlByName(@RequestParam("taskName") String taskName) {
        ResponseResult result = new ResponseResult();
        try {
            DataCrawlService dataCrawlService = dataCrawlContext.getService(taskName);
            if (dataCrawlService == null) {
                //不存在则查询数据
                QueryWrapper<CrawlTask> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("taskName", taskName);
                CrawlTask crawlTask = crawlTaskMapper.selectOne(queryWrapper);
                if (crawlTask != null) {
                    //如果处于等待状态，则直接取消等待删除数据
                    if (crawlTask.getTaskStatus().equals(CrawlTaskStatus.WAITING.name())) {
                        crawlTaskMapper.deleteById(crawlTask.getId());
                    } else if (crawlTask.getTaskType().equals(CrawlTaskStatus.RUNNING.name())) {
                        //如果处于运行中状态但是系统中没有，则对数据作正常结束处理
                        crawlTask.setTaskType(CrawlTaskStatus.END.name());
                        crawlTaskMapper.updateById(crawlTask);
                    }
                }
            } else {
                dataCrawlService.stopCrawl();
            }
            result.buildCode(200).buildMessage("操作成功").setData(true);
        } catch (Exception e) {
            result.buildCode(50001).buildMessage("操作失败").setData(false);
            LOGGER.error(e.getMessage(), e);
        }
        return result;
    }

    /**
     * 获得服务状态
     * @param taskName 服务名称
     * @return ResponseResult
     */
    @GetMapping("/get/status")
    public ResponseResult checkTaskStatus(@RequestParam("taskName") String taskName) {
        ResponseResult result = new ResponseResult();
        try {
            QueryWrapper<CrawlTask> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("taskName", taskName);
            CrawlTask crawlTask = crawlTaskMapper.selectOne(queryWrapper);
            result.buildCode(200).buildMessage("操作成功").setData(crawlTask);
        } catch (Exception e) {
            result.buildCode(50001).buildMessage("操作失败").setData(false);
            LOGGER.error(e.getMessage(), e);
        }
        return result;
    }

    /**
     * 文件下载
     * @param fileName 文件下载地址
     * @param response 响应结果
     * @return null
     */
    @GetMapping("/downloadCrawlFile")
    public String downloadCrawlFile(@RequestParam("fileName") String fileName, HttpServletResponse response) {
        String filePath = crawlPath + "/" + fileName;
        FileDownload.download(filePath, response);
        return null;
    }
}
